package br.com.wssa.smmb.service.impl;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.com.wssa.smmb.dao.GrupoUsuarioDAO;
import br.com.wssa.smmb.dao.RoleDAO;
import br.com.wssa.smmb.dao.UsuarioDAO;
import br.com.wssa.smmb.dto.MensagemDTO;
import br.com.wssa.smmb.entidades.Grupo;
import br.com.wssa.smmb.entidades.Usuario;
import br.com.wssa.smmb.enums.TipoUsuarioEnum;
import br.com.wssa.smmb.exception.BusinessException;
import br.com.wssa.smmb.exception.ServiceException;
import br.com.wssa.smmb.service.UsuarioService;

@Service("usuarioService")
public class UsuarioServiceImpl implements UsuarioService {

	@Autowired
	private UsuarioDAO usuarioDAO;

	@Autowired
	private GrupoUsuarioDAO grupoUsuarioDAO;

	@Autowired
	private RoleDAO roleDAO;

	private static final Logger LOGGER = Logger.getLogger(UsuarioServiceImpl.class);

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void cadastrarPessoaFisica(Usuario usuario) throws BusinessException, ServiceException {
		try {
			validarPessoaFisica(usuario);
			Grupo grupo = grupoUsuarioDAO.get(TipoUsuarioEnum.PESSOA_FISICA.getCodigo());
			grupo.getRoles();
			usuario.setGrupo(grupo);
			usuarioDAO.persistir(usuario);
		} catch (BusinessException e) {
			throw e;
		} catch (Exception e) {
			LOGGER.error(e.getStackTrace());
			throw new ServiceException(e.getMessage(), e);
		}
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void cadastrarPessoaJuridica(Usuario usuario) throws BusinessException, ServiceException {
		try {
			validarPessoaJuridica(usuario);
			usuarioDAO.persistir(usuario);
			Grupo grupo = grupoUsuarioDAO.get(TipoUsuarioEnum.PESSOA_JURIDICA.getCodigo());
			grupo.getUsuarios().add(usuario);
			grupoUsuarioDAO.persistir(grupo);
		} catch (BusinessException e) {
			throw e;
		} catch (Exception e) {
			LOGGER.error(e);
			throw new ServiceException(e.getMessage(), e);
		}
	}
	
	@Override
	public void validarLogin(String email, String senha) throws BusinessException, ServiceException {
		try {
			MensagemDTO mensagem = new MensagemDTO();
			boolean loginInvalido = false;
			StringBuilder erro = new StringBuilder();
			if (StringUtils.isEmpty(email)) {
				erro.append("Email");
			}
			if (StringUtils.isEmpty(senha)) {
				if (StringUtils.isNotBlank(erro.toString())) {
					erro.append(", ");
				}
				erro.append("Senha");
			}
			if (StringUtils.isNotBlank(erro.toString())) {
				String msg = "Preenchimento Obrigatório do(s) campo(s): " + erro.toString();
				mensagem.setMsgAdvertencia(msg);
				loginInvalido = true;
			} else {
				if (usuarioDAO.obterUsuarioPorEmailSenha(email, senha) == null) {
					mensagem.setMsgErro("Usuário ou Senha Invalida!");
					loginInvalido = true;
				}
			}
			if (loginInvalido) {
				throw new BusinessException(mensagem);
			}
		} catch (BusinessException e) {
			throw e;
		} catch (Exception e) {
			LOGGER.error(e);
			throw new ServiceException(e.getMessage(), e);
		}
	}

	private void validarPessoaFisica(Usuario usuario) throws BusinessException {
		MensagemDTO mensagem = new MensagemDTO();
		boolean usuarioInvalido = false;
		StringBuilder erro = new StringBuilder();
		if (StringUtils.isBlank(usuario.getSenha())) {
			erro.append("Senha invalida!");
			usuarioInvalido = true;
		}
		if (!usuario.getSenha().equals(usuario.getConfirmaSenha())) {
			erro.append("Confirmação da Senha inválida!");
			usuarioInvalido = true;
		}
		if (usuarioDAO.obterUsuarioPorEmail(usuario.getEmail()) != null) {
			erro.append("Login existente!");
			usuarioInvalido = true;
		} else if (usuarioDAO.obterUsuarioPorEmail(usuario.getEmail()) != null) {
			erro.append("Email já existente!");
			usuarioInvalido = true;
		}
		if (StringUtils.isNotBlank(erro.toString())) {
			mensagem.setMsgErro(erro.toString());
		}
		if (usuarioInvalido) {
			throw new BusinessException(mensagem);
		}
	}
	
	private void validarPessoaJuridica(Usuario usuario) throws BusinessException{
		validarPessoaFisica(usuario);
	}

	@Override
	public void enviarNovaSenha(String email) throws BusinessException, ServiceException {
		try {
			validarEmail(email);
			enviarEmail(email);
		} catch (BusinessException e) {
			throw e;
		} catch (Exception e) {
			LOGGER.error(e);
			throw new ServiceException(e.getMessage(), e);
		}
	}
	


	private void validarEmail(String email) throws BusinessException {
		MensagemDTO mensagem = new MensagemDTO();
		boolean emailInvalido = false;
		StringBuilder erro = new StringBuilder();
		if (StringUtils.isEmpty(email)) {
			erro.append("Email");
		}
		if (StringUtils.isNotBlank(erro.toString())) {
			String msg = "Preenchimento Obrigatório do campo: " + erro.toString();
			mensagem.setMsgAdvertencia(msg);
			emailInvalido = true;
		} else {
			if (usuarioDAO.obterUsuarioPorEmail(email) == null) {
				mensagem.setMsgErro("Não existe usuário cadastrado para esse email");
				emailInvalido = true;
			}
		}
		if (emailInvalido) {
			throw new BusinessException(mensagem);
		}
	}
	
	private void enviarEmail(String email) throws BusinessException{
		MensagemDTO mensagem = new MensagemDTO();
		mensagem.setMsgSucesso("Uma nova senha foi enviada para o seu email");
		throw new BusinessException(mensagem);
	}
	// Usando SpEL
	/*
	 * @Secured("hasRole('ROLE_ADMIN')") public void banir(Usuario usuario) {
	 * 
	 * } // Passando uma lista de permissões
	 * 
	 * @Secured({"ROLE_ADMIN", "ROLE_MODERADOR"}) public void advertir(Usuario
	 * usuario, String mensagem) {
	 * 
	 * }
	 */
}
